import {api_login, api_logout} from '@/api/admin/auth'
import {profile as apiAdminInfo} from '@/api/admin/admin'
import {
  setAdminToken,
  getAdminToken,
  delAdminToken,
  setUsername,
  delUsername,
  setNickname,
  delNickname,
  setAvatar,
  delAvatar
} from '@/utils/auth'
import router, {
  resetRouter
} from '@/router'

const state = {
  adminToken: getAdminToken(),
  username: '',
  nickname: '',
  avatar: '',
  adminInfo: [],
  asyncRoutes: [],
  roleRoutes: []
}

const mutations = {
  SET_ADMINTOKEN: (state, adminToken) => {
    state.adminToken = adminToken
  },
  SET_USERNAME: (state, username) => {
    state.username = username
  },
  SET_NICKNAME: (state, nickname) => {
    state.nickname = nickname
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_ADMININFO: (state, adminInfo) => {
    state.adminInfo = adminInfo
  },
  SET_ASYNCROUTES: (state, async_routes) => {
    state.asyncRoutes = async_routes
  },
  SET_ROLEROUTES: (state, role_routes) => {
    state.roleRoutes = role_routes
  }
}

const actions = {
  // 登录
  login({commit}, loginData) {
    const {
      username,
      password,
      captcha_key,
      captcha_code,
      remember
    } = loginData
    return new Promise((resolve, reject) => {
      api_login({
        username: username,
        password: password,
        captcha_key: captcha_key,
        captcha_code: captcha_code,
        remember: remember
      }).then(response => {
        const {data} = response
        commit('SET_ADMINTOKEN', data.token)
        setAdminToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // 获取管理员信息
  adminInfo({commit, state}) {
    return new Promise((resolve, reject) => {
      apiAdminInfo({
        token: state.adminToken
      }).then(response => {
        const {data} = response
        if (!data) {
          reject('授权失败, 请重新登录！')
        }

        const {
          username,
          nickname,
          full_avatar,
          async_routes,
          role_routes
        } = data

        // 权限必须是一个非空数组
        if (!role_routes || role_routes.length <= 0) {
          reject('获取权限失败, 请重新登录！')
        }

        commit('SET_USERNAME', username)
        commit('SET_NICKNAME', nickname)
        commit('SET_AVATAR', full_avatar)
        commit('SET_ADMININFO', data)
        commit('SET_ASYNCROUTES', async_routes)
        commit('SET_ROLEROUTES', role_routes)
        setUsername(username)
        setNickname(nickname)
        setAvatar(full_avatar)
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  // 退出
  logout({commit, state, dispatch}) {
    return new Promise((resolve, reject) => {
      api_logout().then(() => {
        commit('SET_ADMINTOKEN', '')
        commit('SET_USERNAME', '')
        commit('SET_NICKNAME', '')
        commit('SET_AVATAR', '')
        commit('SET_ASYNCROUTES', [])
        commit('SET_ROLEROUTES', [])
        delAdminToken()
        delUsername()
        delNickname()
        delAvatar()
        resetRouter()

        // 重置访问的视图和缓存的视图
        dispatch('tagsView/delAllViews', null, {root: true})

        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // 重置token
  resetAdminToken({commit}) {
    return new Promise(resolve => {
      commit('SET_ADMINTOKEN', '')
      commit('SET_ROLEROUTES', [])
      delAdminToken()
      resolve()
    })
  },

  // 动态修改权限
  async changeRoles({commit, dispatch}, role) {
    const adminToken = role + '-adminToken'

    commit('SET_ADMINTOKEN', adminToken)
    setAdminToken(adminToken)

    const {async_routes, role_routes} = await dispatch('admin/adminInfo')

    resetRouter()

    // 根据权限生成可访问路由
    const accessRoutes = await dispatch('permission/generateRoutes', {'async_routes': async_routes, 'role_routes': role_routes}, {root: true})

    // 动态添加可访问路由
    router.addRoutes(accessRoutes)

    // 重置访问的视图和缓存的视图
    dispatch('tagsView/delAllViews', null, {root: true})
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
